package com.ifacebox.client.tools.utils;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

/**
 * @author Znn
 */
public class ImageUtils {
    public static final String[] IMAGE_FORMAT = {"jpg", "jpeg", "png", "bmp", "gif"};

    public static BufferedImage readImage(File file) {
        if (file == null || !file.exists()) {
            return null;
        }
        try {
            return ImageIO.read(file);
        } catch (IOException e) {
            return null;
        }
    }

    public static BufferedImage readImage(byte[] data) {
        if (data == null || data.length == 0) {
            return null;
        }
        try (ByteArrayInputStream bis = new ByteArrayInputStream(data)) {
            return ImageIO.read(bis);
        } catch (IOException e) {
            return null;
        }
    }

    public static byte[] readImage(BufferedImage image) {
        return readImage(image, IMAGE_FORMAT[0]);
    }

    public static byte[] readImage(BufferedImage image, String format) {
        if (image == null) {
            return null;
        }
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            if (ImageIO.write(image, format, bos)) {
                return bos.toByteArray();
            }
            return null;
        } catch (IOException e) {
            return null;
        }
    }

    public static boolean writeImage(BufferedImage image, File file) {
        return writeImage(image, IMAGE_FORMAT[0], file);
    }

    public static boolean writeImage(BufferedImage image, String format, File file) {
        if (image == null || file == null) {
            return false;
        }
        try {
            return ImageIO.write(image, format, file);
        } catch (IOException e) {
            return false;
        }
    }

    public static Image scaleImage(BufferedImage image, float scale, int hints) {
        if (image == null) {
            return null;
        }
        return scaleImage(image, (int) (image.getWidth() * scale), (int) (image.getHeight() * scale), hints);
    }

    public static Image scaleImage(BufferedImage image, int width, int height, int hints) {
        if (image == null) {
            return null;
        }
        return image.getScaledInstance(width == 0 ? image.getWidth() : width, height == 0 ? image.getHeight() : height, hints);
    }

    public static Image scaleImage(Image image, float scale, int hints) {
        if (image == null) {
            return null;
        }
        return scaleImage(image, (int) (image.getWidth(null) * scale), (int) (image.getHeight(null) * scale), hints);
    }

    public static Image scaleImage(Image image, int width, int height, int hints) {
        if (image == null) {
            return null;
        }
        return image.getScaledInstance(width == 0 ? image.getWidth(null) : width, height == 0 ? image.getHeight(null) : height, hints);
    }

    public static Image resizeImage(BufferedImage image, int width, int height, int hints) {
        if (image == null) {
            return null;
        }
        return scaleImage(image, image.getWidth() < image.getHeight() ? -1 : width, image.getWidth() > image.getHeight() ? -1 : height, hints);
    }

    public static Image resizeImage(Image image, int width, int height, int hints) {
        if (image == null) {
            return null;
        }
        return scaleImage(image, image.getWidth(null) < image.getHeight(null) ? -1 : width, image.getWidth(null) > image.getHeight(null) ? -1 : height, hints);
    }

    public static BufferedImage drawImage(Image image) {
        if (image == null) {
            return null;
        }
        Graphics2D g2d = null;
        try {
            BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
            g2d = bi.createGraphics();
            g2d.drawImage(image, 0, 0, null);
            return bi;
        } finally {
            if (g2d != null) {
                g2d.dispose();
            }
        }
    }

    public static BufferedImage cutImage(BufferedImage image, Rectangle rect) {
        return cutImage(image, rect, 0, 0);
    }

    public static BufferedImage cutImage(BufferedImage image, Rectangle rect, int grow) {
        return cutImage(image, rect, grow, grow);
    }

    public static BufferedImage cutImage(BufferedImage image, Rectangle rect, int h, int v) {
        if (image == null) {
            return null;
        }
        rect.grow(h, v);
        rect = new Rectangle(0, 0, image.getWidth(), image.getHeight()).intersection(rect);
        return image.getSubimage(rect.x, rect.y, rect.width, rect.height);
    }

    public static void showImage(Image image) {
        JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(image), JLabel.CENTER), image.getWidth(null) + "x" + image.getHeight(null), JOptionPane.PLAIN_MESSAGE);
    }

    public static void main(String[] args) {
        BufferedImage image = ImageUtils.readImage(new File("d:/Temp/Rx/a.jpg"));
        Image img = ImageUtils.resizeImage(image, 100, 1000, Image.SCALE_SMOOTH);
        ImageUtils.showImage(img);
    }
}
